package com.lvmama.controller.rhino.statisticcode;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.lvmama.common.enums.CommonType;
import com.lvmama.common.result.CodeMessage;
import com.lvmama.common.result.Result;
import com.lvmama.common.utils.EncryptionKey;
import com.lvmama.pojo.dto.rhino.topic.StatisticCodesConditionVO;
import com.lvmama.pojo.entity.rhino.topic.StatisticCode;
import com.lvmama.service.rhino.topic.StatisticCodeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @param
 * @Title:
 * @Author:wangpeng
 * @Description: TODO(这里用一句话描述这个方法的作用)
 * @return
 * @throws
 */
@RestController
@Slf4j
@RequestMapping(value = "/code")
public class StatisticCodeController {
	@Autowired
    StatisticCodeService service;

	@PostMapping(value = "getAllList")
	PageInfo<StatisticCode> getAllList(@RequestBody StatisticCodesConditionVO sc){
		log.info("getAllList start");
		PageInfo<StatisticCode> result = null;
		try {
			result = service.getAllList(sc);
		}catch (Exception e){
			log.error("getAllList error",e.getMessage(),e);
		}
		log.info("getAllList end");
		return result;
	}

	/**
	 * 获取treeview的数据
	 *
	 * @return
	 */
	@GetMapping(value = "treeviewStr")
	public Result<String> treeviewStr() {
		//获取统计code码所有数据
		List<StatisticCode> statisticCodes = null;
		try {
			statisticCodes = service.getStatisticCodeList();
		}catch (Exception e){
			log.error("treeviewStr error",e.getMessage(),e);
		}
		JSONArray statisticCodeJson1 = new JSONArray();
		//通过循环遍历拼接json数据
		for (StatisticCode statisticCode : statisticCodes) {
			try{
				if (statisticCode != null && statisticCode.getIsAdd() != null && !"".equals(statisticCode.getIsAdd())){
					String isAdd = statisticCode.getIsAdd();
					String type = null;
					if ("1".equals(isAdd)) {
						type = "folder";
					} else {
						type = "item";
					}
					JSONObject node = new JSONObject();
					node.put("id", statisticCode.getId());
					node.put("name", statisticCode.getName());
					node.put("parentId", statisticCode.getParentId());
					node.put("type", type);
					node.put("code", statisticCode.getCode());
					statisticCodeJson1.add(node);
				}
			}catch (Exception e){
				e.printStackTrace();
			}

		}

		for (int i = 0; i < statisticCodeJson1.size(); i++) {
			JSONObject obj1 = statisticCodeJson1.getJSONObject(i);
			JSONObject objName = new JSONObject();
			JSONArray arr1 = new JSONArray();
			for (int j = 0; j < statisticCodeJson1.size(); j++) {
				JSONObject obj2 = statisticCodeJson1.getJSONObject(j);
				if (obj1.get("id").equals(obj2.get("parentId"))) {
					objName.put(obj2.get("name").toString(), obj2);
				}
			}
			arr1.add(objName);
			obj1.put("children", arr1);
		}
		JSONArray arr = new JSONArray();
		JSONObject objName = new JSONObject();
		for (int i = 0; i < statisticCodeJson1.size(); i++) {
			JSONObject obj1 = statisticCodeJson1.getJSONObject(i);
			if (obj1.get("parentId") == null) {
				objName.put(obj1.get("name").toString(), obj1);
			}
		}
		arr.add(objName);
		String str = arr.toJSONString();
		return Result.success(str);
	}

	@GetMapping(value = "edit")
	Result<Map<String, Object>> edit(String codeId){
		Map<String, Object> result = getResult();
		StatisticCode statisticCode = new StatisticCode();
		statisticCode.setId(Integer.parseInt(codeId));
		List<StatisticCode> childCodeList = null;
		//根据条件查询code对象
		try {
			statisticCode = service.selectStatisticCode(statisticCode);
			//根据id查询子节点
			childCodeList = service.queryChildCodeListByParentId(statisticCode.getId());
		}catch (Exception e){
			log.error("edit error",e.getMessage(),e);
		}
		//是否允许编辑前端isAdd选项
		boolean showIsAdd = false;
		if (childCodeList != null && childCodeList.size() != 0) {
			showIsAdd = true;
		}
		if (statisticCode != null) {
			result.put("code", "1");
			result.put("statisticCode", statisticCode);
			result.put("parentCode", statisticCode.getParent());
			result.put("showIsAdd", showIsAdd);
		}
		return Result.success(result);
	}

	@PostMapping(value = "save")
	Result<Map<String, Object>> saveCode(@RequestBody StatisticCode statisticCode, @RequestParam(value = "parentId") Integer parentId, @RequestParam(value = "isNew") boolean isNew){
		StatisticCode parentCode = new StatisticCode();
		parentCode.setId(parentId);
		statisticCode.setParent(parentCode);
		Map<String, Object> result = getResult();
		int flag = 0;
		//当编辑code码name为修改时，则传递为false;若新增code码和编辑code码时修改了name，则传递为true
		try{
			if (isNew) {
				//判断code码的name是否已存在
				int isExist = service.getCountForName(statisticCode.getName()) == 0 ? 0 : service.getCountForName(statisticCode.getName());
				if (isExist != 0) {
					result.put("code", 1);
					result.put("msg", "操作失败,该中文名称的code码已存在");
					return Result.error(CodeMessage.SERVER_ERROR);
				}
			}
			//操作code码信息
			flag = service.operationCode(statisticCode);
		}catch (Exception e){
			log.error("saveCode error",e.getMessage(),e);
		}
		if (flag == 1) {
			result.put("code", 1);
			result.put("msg", "code码操作成功");
		} else {
			result.put("code", 1);
			result.put("msg", "code码操作失败");
		}
		return Result.success(result);
	}

	@GetMapping(value = "treegrid")
	Result<String> treegrid( @RequestParam(value = "parentName") String parentName){
		List<StatisticCode> statisticCodes;
		StatisticCode statisticParentCode = new StatisticCode();
		try{
			if ("all".equals(parentName)) {
				//查询所有code码信息
				statisticCodes = service.getStatisticCodeList();
			} else {
				statisticParentCode.setName(parentName);
				//根据条件查询code对象
				statisticParentCode = service.selectStatisticCode(statisticParentCode);
				//根据父级code码，查询子级对象
				if ("4".equals(statisticParentCode.getCode())) {
					statisticCodes = service.queryChildCodeListByParentId(statisticParentCode.getId());
					statisticCodes.add(statisticParentCode);
				} else {
					statisticCodes = service.getParentAndChildrenLikeCodeObj(statisticParentCode.getCode());
				}
			}
		}catch (Exception e){
			log.error("treegrid error",e.getMessage(),e);
			return Result.error(CodeMessage.SERVER_ERROR);
		}
		//List<StatisticCode> statisticCodes = statisticCodeService.getStatisticCodeList();
		JSONArray statisticCodeJsons = new JSONArray();
		//拼接json数据
		if (statisticCodes != null && statisticCodes.size() > 0){
			for (StatisticCode statisticCode : statisticCodes) {
				if (statisticCode != null && statisticCode.getIsAdd() != null && !"".equals(statisticCode.getIsAdd())){
					String isAdd = "1".equals(statisticCode.getIsAdd()) ? "允许" : "不允许";
					StatisticCode codeObj = statisticCode.getParent();
					String parent = null;
					if (codeObj != null) {
						parent = codeObj.getName();
					}
					JSONObject node = new JSONObject();
					node.put("id", statisticCode.getId());
					node.put("name", statisticCode.getName());
					node.put("enName", statisticCode.getEnName());
					node.put("parentId", statisticCode.getParentId());
					node.put("parent", parent);
					node.put("code", statisticCode.getCode());
					node.put("isAdd", isAdd);
					node.put("codeType", statisticCode.getCodeType());
					node.put("codeTypeLevel", statisticCode.getCodeTypeLevel());
					statisticCodeJsons.add(node);
				}
			}
		}

		if (statisticCodeJsons != null ){
			for (int i = 0; i < statisticCodeJsons.size(); i++) {
				JSONObject obj1 = statisticCodeJsons.getJSONObject(i);
				JSONArray arr1 = new JSONArray();
				for (int j = 0; j < statisticCodeJsons.size(); j++) {
					JSONObject obj2 = statisticCodeJsons.getJSONObject(j);
					if (obj1.get("id") != null && obj1.get("id").equals(obj2.get("parentId"))) {
						arr1.add(obj2);
					}
				}
				obj1.put("children", arr1);
			}
		}
		JSONArray arr = new JSONArray();
		//当查询所有code数据时
		if ("all".equals(parentName) ) {
			if (statisticCodeJsons != null){
				for (int i = 0; i < statisticCodeJsons.size(); i++) {
					JSONObject obj1 = statisticCodeJsons.getJSONObject(i);
					if (obj1.get("parentId") == null) {
						arr.add(obj1);
					}
				}
			}
			//查询指定code码数据时
		} else {
			if (statisticCodeJsons != null){
				for (int i = 0; i < statisticCodeJsons.size(); i++) {
					JSONObject obj1 = statisticCodeJsons.getJSONObject(i);
					String id = obj1.get("id").toString();
					if (id != null && id.equals(statisticParentCode.getId().toString())) {
						arr.add(obj1);
					}
				}
			}
		}
		return Result.success(arr.toJSONString());
	}


	@GetMapping(value = "saveCodeTree")
	Result<Map<String, Object>> saveCodeTree( @RequestParam(value = "codeInfo") String codeInfo){
		Map<String, Object> result = getResult();
		String codeStr = StringEscapeUtils.unescapeXml(codeInfo);
		JSONObject code = JSONObject.parseObject(codeStr);
		StatisticCode statisticCode = new StatisticCode();
		statisticCode.setId((Integer) code.get("id"));
		statisticCode.setName(code.get("name").toString());
		statisticCode.setEnName(code.get("enName").toString());
		statisticCode.setCode(code.get("code").toString());
		String parentId = null;
		if (code.get("parentId") != null) {
			parentId = code.get("parentId").toString();
		}
		int flag = 0;
		try {
			if (StringUtils.isNotEmpty(parentId) && ("15".equals(parentId) || "434".equals(parentId))) {
				flag = service.updateOtherCode(statisticCode);
			} else {
				flag = service.updateCode(statisticCode);
			}
		}catch (Exception e){
			log.error("saveCodeTree error",e.getMessage(),e);
			return Result.error(CodeMessage.SERVER_ERROR);
		}
		if (flag == 1) {
			result.put("statisticCodes", treeviewStr());
			result.put("code", 1);
			result.put("msg", "code码操作成功");
		} else {
			result.put("code", 1);
			result.put("msg", "code码操作失败");
		}
		return Result.success(result);
	}

	@GetMapping(value = "createCode")
	Result<Map<String, Object>> createCode( @RequestParam(value = "parentCode") String parentCode){
		Map<String, Object> result = getResult();
		//获取父级code码的第一个字符
		String firstStr = parentCode.substring(0, 1);
		//查询前缀为parentCode的code码信息
		List<String> codesList = null;
		try {
			if ("3zhTi".equals(parentCode)) {
				codesList = service.getZhtiLikeCode(parentCode);
			} else if ("4".equals(parentCode)) {
				codesList = service.getPitLikeCode();
			} else {
				codesList = service.getLikeCodes(parentCode);
			}
		}catch (Exception e){
			log.error("createCode error",e.getMessage(),e);
		}

		EncryptionKey encryptionKey = new EncryptionKey();

		//父级code码的长度
		int digits = parentCode.length();
		//随机数的位数(后面通过调用getCode(count)方法生成随机数)
		int count = 0;
		String codeType = "";
		//code码类型级别
		String codeTypeLevel = "";
		if (EncryptionKey.CHANNEL_FIRST_CHARACTER.equals(firstStr)) {//渠道级别的首字符为1
			//code码类型为渠道(Channel)
			codeType = EncryptionKey.CODETYPE_CHANNEL;
			switch (digits) {
				case 1:
					count = 1;
					codeTypeLevel = "C2";
					break;
				case 2:
					codeTypeLevel = "C3";
					//内部渠道code码为"11"
					if ("11".equals(parentCode)) {
						count = 4;
					} else {
						count = 1;
					}
					break;
				case 3:
					codeTypeLevel = "C4";
					count = 3;
					break;
				default:
					break;
			}
		} else if (EncryptionKey.DEVICE_FIRST_CHARACTER.equals(firstStr)) {//渠道级别的首字符为2
			codeTypeLevel = "D2";
			//code码类型为渠道(Device)
			codeType = EncryptionKey.CODETYPE_DEVICE;
			count = 3;
		} else if (EncryptionKey.PAGE_FIRST_CHARACTER.equals(firstStr)) {//渠道级别的首字符为3
			//code码类型为渠道(Page)
			codeType = EncryptionKey.CODETYPE_PAGE;
			switch (parentCode) {
				case "3":
					codeTypeLevel = "P2";
					count = 4;
					break;
				default:
					codeTypeLevel = "P3";
					count = 3;
					break;
			}
		}
		//验证是否存在，若存在，则重新生成code码
		String codeData = encryptionKey.validateCode(codesList, parentCode, count);
		result.put("code", "1");
		result.put("msg", codeData);
		result.put("codeType", codeType);
		result.put("codeTypeLevel", codeTypeLevel);
		return Result.success(result);
	}

	@GetMapping(value = "createPitCode")
	Result<Map<String, Object>> createPitCode( @RequestParam(value = "page") String page,@RequestParam(value = "pitName") String pitName){
		Map<String, Object> result = getResult();
		String codeType = "Pit";
		String codeTypeLevel = "K2";
		StatisticCode statisticCode = new StatisticCode();
		//验证是否存在，若存在，不用重新生成
		StatisticCode statisticCode2 = new StatisticCode();
		statisticCode.setName(page);
		statisticCode.setIsAdd(CommonType.DISSHOW.getStringValue());
		String pageTag = null;
		try{
			statisticCode = service.selectStatisticCode(statisticCode);
			String code = statisticCode.getCode();
			pageTag = code.substring(code.length() - 3);

			statisticCode2.setCode(pageTag + pitName);
			statisticCode2 = service.selectStatisticCode(statisticCode2);
		}catch (Exception e){
			log.error("createPitCode error",e.getMessage(),e);
		}
		if (statisticCode2 != null) {
			result.put("code", "-1");
			result.put("errorMsg", "该坑位已存在！");
			return Result.success(result);
		}
		result.put("code", "1");
		result.put("msg", pageTag + pitName);
		result.put("codeType", codeType);
		result.put("codeTypeLevel", codeTypeLevel);
		return Result.success(result);
	}

	@GetMapping(value = "getParent")
	Result<Map<String, Object>> getParent( @RequestParam(value = "nodeHtml") String nodeHtml){
		Map<String, Object> result = getResult();
		StatisticCode statisticCode = new StatisticCode();
		statisticCode.setName(nodeHtml);
		statisticCode.setIsAdd(CommonType.ENSHOW.getStringValue());
		try {
			statisticCode = service.selectStatisticCode(statisticCode);
		}catch (Exception e){
			log.error("getParent error",e.getMessage(),e);
		}
		//新增坑位时查询出所有的页面
		List<String> pageAll = null;
		if ("坑位".equals(nodeHtml)) {
			//使用Redis缓存，提升效率  //
			/**修改可以名称由原来的rhino_statistic_code_page_son 改成rhino_statistic_code_page_sons
			 * 原来的可以存储的值只有首页
			 * */
			String key = "rhino_statistic_code_page_sons";
			try {
				pageAll = service.getPageAllSonName();
			}catch (Exception e){
				log.error("getParent error",e.getMessage(),e);
			}
			statisticCode.setPageList(pageAll);
		}
		if (statisticCode != null) {
			String parentCode = statisticCode.getCode();
			if (!"4".equals(parentCode)) {
				//获取父级code码的第一个字符
				String firstStr = parentCode.substring(0, 1);
				//查询前缀为parentCode的code码信息
				List<String> codesList = null;
				try{
					if ("3zhTi".equals(parentCode)) {
						codesList = service.getZhtiLikeCode(parentCode);
					} else {
						codesList = service.getLikeCodes(parentCode);
					}
				}catch (Exception e){
					log.error(" getParent error",e.getMessage(),e);
				}
				//父级code码的长度
				int digits = parentCode.length();
				//随机数的位数(后面通过调用getCode(count)方法生成随机数)
				int count = 0;
				if (EncryptionKey.CHANNEL_FIRST_CHARACTER.equals(firstStr)) {//渠道级别的首字符为1
					switch (digits) {
						case 1:
							count = 1;
							break;
						case 2:
							//内部渠道code码为"11"
							if ("11".equals(parentCode)) {
								count = 4;
							} else {
								count = 1;
							}
							break;
						case 3:
							count = 3;
							break;
						default:
							break;
					}
				} else if (EncryptionKey.DEVICE_FIRST_CHARACTER.equals(firstStr)) {//渠道级别的首字符为2
					count = 3;
				} else if (EncryptionKey.PAGE_FIRST_CHARACTER.equals(firstStr)) {//渠道级别的首字符为3
					switch (parentCode) {
						case "3":
							count = 4;
							break;
						default:
							count = 3;
							break;
					}
				}
				if (codesList == null || codesList.size() >= Math.pow(EncryptionKey.s.length, count)) {
					result.put("code", "-1");
					result.put("msg", "该级别下的随机code码已使用完毕,不可创建子级code码！");
					return Result.success(result);
				}
			}
			result.put("code", "1");
			result.put("msg", statisticCode);
		}
		return Result.success(result);
	}




	private Map<String, Object> getResult() {
		Map<String, Object> result = new HashMap<String, Object>();
		result.put("code", "-1");
		result.put("msg", "该code码不能创建子级code码！");
		return result;
	}

}
